﻿
/*----------------------------------------------------------------
 * 创建时间：2023/8/7 17:16:00
 * 作  者：wenlli 
 * 项  目：Minotaur.App.Modules.FlowProcess 
 * 描  述： 控制器公共类
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时  间：
 * 修改说明：
 * 
 *----------------------------------------------------------------*/


using MaterialDesignThemes.Wpf;
using Minotaur.App.Core;
using Minotaur.App.Core.Contrls;
using Minotaur.App.Domains.Dto.Flow;
using Minotaur.App.Domains.Enum;
using Minotaur.App.Modules.FlowProcess.Control;
using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace Minotaur.App.Modules.FlowProcess
{
    /// <summary>
    /// 控制器公共类
    /// </summary>
    public static class ControlCommon
    {
        /// <summary>
        /// 设置背景色
        /// </summary>
        /// <param name="userControl"></param>
        public static List<Button> SetBackground(UserControl userControl)
        {
            List<Button> btns = CoordinateUilts.GetChildObjects<Button>(userControl.Parent).Where(o => !string.IsNullOrEmpty(o.Tag + "") && o.Content is null).ToList();
            foreach (var item in btns)
            {
                PackIcon packIcon = new PackIcon()
                {
                    Background = new SolidColorBrush(Colors.Snow),
                    Kind = PackIconKind.Close,
                    Foreground = new SolidColorBrush(Colors.Snow),
                };
                item.Content = packIcon;
            }
            return btns;
        }


        /// <summary>
        /// 清除背景色
        /// </summary>
        /// <param name="buttons"></param>
        public static void ClearButonContent(UserControl userControl)
        {
            List<Button> btns = CoordinateUilts.GetChildObjects<Button>(userControl.Parent).Where(o => !string.IsNullOrEmpty(o.Tag + "")&& new string[] { "left", "right", "top", "bottom" }.Contains(o.Tag + "")).ToList();
            //List<FlowLineControl1> flowLines = CoordinateUilts.GetChildObjects<FlowLineControl1>(userControl.Parent);
            //List<Button> linButtons = flowLines.Select(o => o.EndButton).ToList();
            //linButtons.AddRange(flowLines.Select(o => o.StartButton));
            //var resutls = btns.Where(p => !linButtons.Any(o => o == p));
            foreach (var item in btns)
            {
                item.Content = null;
            }
        }
        /// <summary>
        /// 计算两个点之间的有向箭头
        /// </summary>
        /// <param name="pathfig">箭头所在的形状</param>
        /// <param name="startPoint">开始点</param>
        /// <param name="endPoint">结束点</param>
        /// <returns>计算好的形状</returns>
        public static void CalculateArrow(Polyline polyseg, Point startPoint, Point endPoint)
        {
            var ArrowLength = 12;
            var ArrowAngle = 50;
            if (polyseg != null)
            {
                var matx = new Matrix();
                Vector vect = startPoint - endPoint;
                //获取单位向量
                vect.Normalize();
                vect *= ArrowLength;
                //旋转夹角的一半
                matx.Rotate(ArrowAngle / 2);

                polyseg.Points.Clear();
                polyseg.Points.Add(endPoint + vect * matx);
                polyseg.Points.Add(endPoint);

                matx.Rotate(-ArrowAngle);
                //计算下半段箭头的点
                polyseg.Points.Add(endPoint + vect * matx);
            }
        }

        /// <summary>
        /// 鼠标拖拽按下事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <param name="userControl"></param>
        public static void PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e, UserControl userControl)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                List<Button> buttons = CoordinateUilts.SetBackground(userControl);
                // Package the data.
                DataObject data = new DataObject();
                FlowStepInfoDto flowStepInfoDto = userControl.DataContext as FlowStepInfoDto;
                data.SetData("Object", flowStepInfoDto);
                Button button = sender as Button;
                data.SetData("btn", button);
                data.SetData("controlWidth", userControl.ActualWidth);
                data.SetData("controlHeight", userControl.ActualHeight);
                // Initiate the drag-and-drop operation.
                DragDrop.DoDragDrop(userControl, data, DragDropEffects.Copy | DragDropEffects.Move);
            }
        }
        /// <summary>
        /// 进行拖拽位置变化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <param name="userControl"></param>
        public static void DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e, UserControl userControl, RoutedEvent NodeMoveDragEvent)
        {
            double nTop = Canvas.GetTop(userControl) + e.VerticalChange;
            double nLeft = Canvas.GetLeft(userControl) + e.HorizontalChange;
            if (nTop > 0 && nLeft > 0 && nTop <= (Application.Current.MainWindow.ActualHeight - 140) && nLeft <= (Application.Current.MainWindow.ActualWidth - 90))
            {
                Canvas.SetLeft(userControl, nLeft);
                Canvas.SetTop(userControl, nTop);
                FlowStepInfoDto flowStepInfoDto = userControl.DataContext as FlowStepInfoDto;
                if (flowStepInfoDto != null)
                {
                    flowStepInfoDto.ToLeft = nLeft;
                    flowStepInfoDto.ToTop = nTop;
                    flowStepInfoDto.Coordinate = new double[] { nLeft, nTop }.ToSafeJson();
                    RoutedEventArgs args = new RoutedEventArgs(NodeMoveDragEvent, flowStepInfoDto);
                    userControl.RaiseEvent(args);
                }
            }
        }

        /// <summary>
        /// 拖拽到目标的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <param name="userControl"></param>
        /// <param name="AddLineEvent"></param>
        public static void Drop(object sender, DragEventArgs e, UserControl userControl, RoutedEvent AddLineEvent, PropType[] propTypes, FlowStepInfoDto flowStepInfo)
        {
            var data = e.Data.GetData("Object") as FlowStepInfoDto;
            var btn = e.Data.GetData("btn") as Button;
            var controlWidth = e.Data.GetData("controlWidth") + "";
            var controlHeight = e.Data.GetData("controlHeight") + "";
            var endButton = sender as Button;
            double[] coordinates = CoordinateUilts.ComputeStartNodeCoordinate(data.Prop.Value, data.Coordinate, double.Parse(controlWidth), double.Parse(controlHeight), btn.Tag + "");
            double[] endCoordinates = CoordinateUilts.ComputeEndNodeCoordinate(flowStepInfo.Prop.Value, flowStepInfo.Coordinate, userControl.ActualWidth, userControl.ActualHeight, endButton.Tag + "");

            ControlCommon.ClearButonContent(userControl);
            if (data != null && propTypes.Any(o => o == data.Prop))
            {
                FlowLineDto flowLineDto = new FlowLineDto()
                {
                    CNName = "连接线",
                    StartAt = coordinates.ToSafeJson(),
                    StartLocation = (LoactionType)Enum.Parse(typeof(LoactionType), btn.Tag + ""),
                    EndAt = endCoordinates.ToSafeJson(),
                    EndLocation = (LoactionType)Enum.Parse(typeof(LoactionType), endButton.Tag + ""),
                    EndId = flowStepInfo.StepId,
                    StartId = data.StepId,
                    ENName = "连接线",
                    VersionId = data.VersionId,
                    LinkId = HashUtilsHelper.GetLongHashCode()
                };
                RoutedEventArgs args = new RoutedEventArgs(AddLineEvent, new AddNewLineParamaterDto() { EndButton = endButton, StartButton = btn, FlowLine = flowLineDto });
                userControl.RaiseEvent(args);
            }
        }
    }
}
